import React, { useState, useEffect, useRef } from 'react';
import Board from './components/Board';
import ControlPanel from './components/ControlPanel';
import Modal from './components/Modal';
import MoveHistory from './components/MoveHistory';
import { getInitialBoard, getNextPlayer, checkWinner, isValidMove, cloneBoard } from './utils/rules';
import './App.css';

const themes = {
  light: 'light',
  dark: 'dark',
};
const BGM_PATH = '/sound/bgm.mp3';

function getAllValidMoves(board, player, history, step) {
  const moves = [];
  for (let x = 0; x < board.length; x++) {
    for (let y = 0; y < board[0].length; y++) {
      const piece = board[x][y].piece;
      if (piece && piece.owner === player) {
        // 普通四方向
        [
          { dx: -1, dy: 0 },
          { dx: 1, dy: 0 },
          { dx: 0, dy: -1 },
          { dx: 0, dy: 1 },
        ].forEach(({ dx, dy }) => {
          const nx = x + dx, ny = y + dy;
          if (nx >= 0 && nx < board.length && ny >= 0 && ny < board[0].length) {
            if (isValidMove(board, { x, y }, { x: nx, y: ny }, player)) {
              if (!isBackMove({ from: { x, y }, to: { x: nx, y: ny } }, history, step)) {
                moves.push({ from: { x, y }, to: { x: nx, y: ny } });
              }
            }
          }
        });
        // 狮虎跳河
        if (piece.type === 'LION' || piece.type === 'TIGER') {
          // 横向
          for (const dy of [-1, 1]) {
            let ny = y + dy;
            while (ny >= 0 && ny < board[0].length && board[x][ny].terrain === 'RIVER') ny += dy;
            if (ny >= 0 && ny < board[0].length && Math.abs(ny - y) > 1) {
              if (isValidMove(board, { x, y }, { x, y: ny }, player)) {
                if (!isBackMove({ from: { x, y }, to: { x, y: ny } }, history, step)) {
                  moves.push({ from: { x, y }, to: { x, y: ny } });
                }
              }
            }
          }
          // 纵向
          for (const dx of [-1, 1]) {
            let nx = x + dx;
            while (nx >= 0 && nx < board.length && board[nx][y].terrain === 'RIVER') nx += dx;
            if (nx >= 0 && nx < board.length && Math.abs(nx - x) > 1) {
              if (isValidMove(board, { x, y }, { x: nx, y }, player)) {
                if (!isBackMove({ from: { x, y }, to: { x: nx, y } }, history, step)) {
                  moves.push({ from: { x, y }, to: { x: nx, y } });
                }
              }
            }
          }
        }
      }
    }
  }
  return moves;
}

function getBoardHash(board, currentPlayer) {
  return (
    currentPlayer + '|' +
    board.map(row => row.map(cell => cell.piece ? cell.piece.owner + cell.piece.type[0] : '_').join('')).join('|')
  );
}

function isBackMove(move, history, step) {
  if (step < 2) return false;
  const last = history[step].move;
  const prev = history[step - 1].move;
  if (!last || !prev) return false;
  // 检查是否同一棋子往返同一路径
  return (
    last.piece && prev.piece &&
    last.piece.type === prev.piece.type &&
    last.piece.owner === prev.piece.owner &&
    last.from.x === move.to.x && last.from.y === move.to.y &&
    last.to.x === move.from.x && last.to.y === move.from.y
  );
}

function App() {
  const [history, setHistory] = useState([{ board: getInitialBoard(), currentPlayer: 0, move: null, hash: getBoardHash(getInitialBoard(), 0) }]);
  const [step, setStep] = useState(0);
  const { board, currentPlayer } = history[step];
  const [selected, setSelected] = useState(null);
  const [movables, setMovables] = useState([]);
  const [theme, setTheme] = useState(themes.light);
  const [aiMode, setAiMode] = useState(false);
  const [draw, setDraw] = useState(false);
  const winner = checkWinner(board);
  const [bgmOn, setBgmOn] = useState(true);
  const bgmRef = useRef(null);

  useEffect(() => {
    document.body.setAttribute('data-theme', theme);
  }, [theme]);

  // 三次循环判和
  useEffect(() => {
    const hash = history[step].hash;
    let count = 0;
    for (let i = 0; i <= step; i++) {
      if (history[i].hash === hash) count++;
    }
    if (count >= 3 && !winner) setDraw(true);
    else setDraw(false);
  }, [history, step, winner]);

  // AI自动走棋
  useEffect(() => {
    if (aiMode && !winner && !draw && currentPlayer === 1) {
      setTimeout(() => {
        const moves = getAllValidMoves(board, 1, history, step);
        if (moves.length > 0) {
          const move = moves[Math.floor(Math.random() * moves.length)];
          const piece = board[move.to.x][move.to.y].piece;
          const newBoard = cloneBoard(board);
          if (piece && piece.type === 'RAT' && board[move.to.x][move.to.y].terrain === 'TRAP') {
            newBoard[move.from.x][move.from.y].piece.hasEnteredTrap = true;
          }
          newBoard[move.to.x][move.to.y].piece = newBoard[move.from.x][move.from.y].piece;
          newBoard[move.from.x][move.from.y].piece = null;
          const hash = getBoardHash(newBoard, getNextPlayer(currentPlayer));
          setHistory(h => h.slice(0, step + 1).concat({
            board: newBoard,
            currentPlayer: getNextPlayer(currentPlayer),
            move: {
              from: { ...move.from },
              to: { ...move.to },
              piece: board[move.from.x][move.from.y].piece,
              capture: !!piece,
              captured: piece ? { ...piece } : null
            },
            hash
          }));
          setStep(s => s + 1);
          setSelected(null);
          setMovables([]);
        }
      }, 600);
    }
    // eslint-disable-next-line
  }, [aiMode, currentPlayer, winner, step, draw]);

  // 背景音乐播放与开关
  useEffect(() => {
    if (!bgmRef.current) {
      bgmRef.current = new window.Audio(BGM_PATH);
      bgmRef.current.loop = true;
      bgmRef.current.volume = 0.4;
    }
    if (bgmOn) {
      bgmRef.current.play().catch(() => {});
    } else {
      bgmRef.current.pause();
    }
    return () => {
      if (bgmRef.current) bgmRef.current.pause();
    };
  }, [bgmOn]);

  // 计算可走格
  const getMovableCells = (x, y, history, step) => {
    const moves = [];
    const dirs = [
      { dx: -1, dy: 0 },
      { dx: 1, dy: 0 },
      { dx: 0, dy: -1 },
      { dx: 0, dy: 1 },
    ];
    for (const { dx, dy } of dirs) {
      const nx = x + dx, ny = y + dy;
      if (nx >= 0 && nx < board.length && ny >= 0 && ny < board[0].length) {
        if (isValidMove(board, { x, y }, { x: nx, y: ny }, currentPlayer)) {
          if (!isBackMove({ from: { x, y }, to: { x: nx, y: ny } }, history, step)) {
            moves.push({ x: nx, y: ny });
          }
        }
      }
    }
    // 狮虎跳河
    const piece = board[x][y]?.piece;
    if (piece && (piece.type === 'LION' || piece.type === 'TIGER')) {
      // 横向
      for (const dy of [-1, 1]) {
        let ny = y + dy;
        while (ny >= 0 && ny < board[0].length && board[x][ny].terrain === 'RIVER') ny += dy;
        if (ny >= 0 && ny < board[0].length && Math.abs(ny - y) > 1) {
          if (isValidMove(board, { x, y }, { x, y: ny }, currentPlayer)) {
            if (!isBackMove({ from: { x, y }, to: { x, y: ny } }, history, step)) {
              moves.push({ x, y: ny });
            }
          }
        }
      }
      // 纵向
      for (const dx of [-1, 1]) {
        let nx = x + dx;
        while (nx >= 0 && nx < board.length && board[nx][y].terrain === 'RIVER') nx += dx;
        if (nx >= 0 && nx < board.length && Math.abs(nx - x) > 1) {
          if (isValidMove(board, { x, y }, { x: nx, y }, currentPlayer)) {
            if (!isBackMove({ from: { x, y }, to: { x: nx, y } }, history, step)) {
              moves.push({ x: nx, y });
            }
          }
        }
      }
    }
    return moves;
  };

  const handleCellClick = (x, y) => {
    if (winner || draw) return;
    const piece = board[x][y]?.piece;
    if (selected) {
      if (selected.x === x && selected.y === y) {
        setSelected(null);
        setMovables([]);
        return;
      }
      if (movables.some(m => m.x === x && m.y === y)) {
        // 检查是否回头
        if (isBackMove({ from: selected, to: { x, y } }, history, step)) {
          alert('不能回头走！');
          return;
        }
        const newBoard = cloneBoard(board);
        // 陷阱标记：老鼠进陷阱
        if (piece && piece.type === 'RAT' && board[x][y].terrain === 'TRAP') {
          newBoard[selected.x][selected.y].piece.hasEnteredTrap = true;
        }
        newBoard[x][y].piece = newBoard[selected.x][selected.y].piece;
        newBoard[selected.x][selected.y].piece = null;
        const hash = getBoardHash(newBoard, getNextPlayer(currentPlayer));
        setHistory(h => h.slice(0, step + 1).concat({
          board: newBoard,
          currentPlayer: getNextPlayer(currentPlayer),
          move: {
            from: { ...selected },
            to: { x, y },
            piece: board[selected.x][selected.y].piece,
            capture: !!piece,
            captured: piece ? { ...piece } : null
          },
          hash
        }));
        setStep(s => s + 1);
        setSelected(null);
        setMovables([]);
      }
    } else {
      if (piece && piece.owner === currentPlayer) {
        setSelected({ x, y });
        setMovables(getMovableCells(x, y, history, step));
      }
    }
  };

  const handleUndo = () => {
    if (step > 0) setStep(step - 1);
    setSelected(null);
    setMovables([]);
  };
  const handleRestart = () => {
    setHistory([{ board: getInitialBoard(), currentPlayer: 0, move: null, hash: getBoardHash(getInitialBoard(), 0) }]);
    setStep(0);
    setSelected(null);
    setMovables([]);
  };

  const lastMove = step > 0 ? history[step].move : null;

  return (
    <div className="app-container">
      <div className="theme-switcher">
        <button className="btn" onClick={() => setTheme(theme === themes.light ? themes.dark : themes.light)}>
          {theme === themes.light ? '🌙 暗黑' : '☀️ 亮色'}
        </button>
        <button className="btn" onClick={() => setAiMode(m => !m)}>
          {aiMode ? '👤 双人' : '🤖 人机'}
        </button>
        <button className="btn" onClick={() => setBgmOn(on => !on)}>
          {bgmOn ? '🔊 背景音乐' : '🔇 静音'}
        </button>
      </div>
      <h1>斗兽棋小游戏</h1>
      <ControlPanel currentPlayer={currentPlayer} winner={winner} onUndo={handleUndo} onRestart={handleRestart} canUndo={step > 0} />
      <Board board={board} selected={selected} movables={movables} onCellClick={handleCellClick} lastMove={lastMove} />
      <MoveHistory history={history} step={step} />
      <Modal show={winner !== null || draw} winner={winner} draw={draw} onRestart={handleRestart} />
      <footer>Made with ❤️ using React</footer>
    </div>
  );
}

export default App; 